import itemModel from 'server/model/itemModel';
import {
    totalConfig,
    propName
} from 'server/config/templateConfig';
import PackageModel from 'server/model/packageModel';
let itemsConfig = totalConfig.item;
const MAX_STACK = 999;

class PackageHandle {
    static getInstance() {
        if (!PackageHandle.instance) {
            PackageHandle.instance = new PackageHandle();
        }
        return PackageHandle.instance;
    }

    //初始化背包
    initPackag(pack) {
        pack = PackageModel.create(pack);
        pack.emptySize = pack.size;
        let items = pack.items;
        for (let i = 0; i < items.length; i++) {
            let itemComponent = items[i];
            if (!itemComponent) {
                continue
            }
            let templateId = itemComponent.templateId;
            // itemComponent = itemModel.create(itemComponent);
            // items[i] = itemComponent;
            itemComponent.pos = Number(i);
            if (!pack.itemsById[templateId]) {
                pack.itemsById[templateId] = [];
            }
            pack.itemsById[templateId].push(itemComponent);
        }
        return pack;
    }

    //获取背包信息
    getInfo(pack) {
        return {
            items: pack.items,
            size: pack.size,
            emptySize: pack.emptySize
        }
    }

    //获取背包大小
    getSize(pack) {
        return pack.size;
    }

    //获取指定位置的物品以及物品的位置信息
    getItemByPos(pack, pos) {
        return pack.items[pos];
    }

    //添加物品
    addItems(pack, items) {
        let size = items.length;
        if (pack.emptySize < size) {
            return -1; //背包空间不足
        }
        for (let i = 0; i < size; i++) {
            let item = items[i];
            this.addItemComponent(pack, item);
        }
        return 0;
    }

    //添加物品
    addItem(pack, itemId, num) {
        if (!itemModel.getItemConfig(itemId)) {
            console.log(`${itemId}该物品不存在`);
            return
        }
        let itemComponent = itemModel.create({
            templateId: itemId,
            stack: num
        });
        return this.addItemComponent(pack, itemComponent);
    }

    //添加物品
    addItemComponent(pack, itemComponent) {
        //判断背包是否有空
        if (pack.emptySize === 0) {
            return -1;
        }
        //判断物品是否可以叠加
        let itemMaxStack = itemModel.getItemConfig(itemComponent.templateId).maxStack || MAX_STACK;
        if (itemMaxStack === 1) {
            //不可叠加，添加到空格子
            this._addItemToPosition(pack, itemComponent);
            return 0;
        }
        //查找物品是否已经存在
        let itemInfoId = pack.itemsById[itemComponent.templateId];
        if (!itemInfoId) {
            //不存在，添加到空格子
            this._addItemToPosition(pack, itemComponent);
        } else {
            let num = itemComponent.stack || 1; //叠加数
            for (let i = 0; i < itemInfoId.length; i++) {
                let p = itemInfoId[i]
                let stack = p.stack
                // if (itemComponent.bind === p.bind) { //是否都是绑定或不绑定
                if ((stack + num) <= MAX_STACK) {
                    p.stack = stack + num;
                    num = 0;
                    return 0;
                } else {
                    num = stack + num - MAX_STACK;
                    p.stack = MAX_STACK;
                }
                // }
            }
            if (num > 0) {
                //剩余的数量添加到空格子
                itemComponent.stack = num;
                this._addItemToPosition(pack, itemComponent);
            }
        }
        return 0;
    }

    //添加物品到空格子
    _addItemToPosition(pack, itemComponent) {
        let pos = this._getEmpty(pack); //获取空格子的下标
        if (pos === -1) {
            return -1;
        }
        itemComponent.pos = pos;
        pack.emptySize -= 1; //空格子数量减一
        pack.items[pos] = itemComponent;
        let itemInfoId = pack.itemsById[itemComponent.templateId];
        //查找物品是否已经存在
        if (itemInfoId) {
            itemInfoId.push(itemComponent);
        } else {
            pack.itemsById[itemComponent.templateId] = [itemComponent];
        }
    }

    //获取一个空格子的下标
    _getEmpty(pack) {
        if (pack.emptySize === 0) {
            return -1;
        }
        for (let i = 0; i < pack.size; i++) {
            if (!pack.items[i]) {
                return i;
            }
        }
    }

    isHasEmpty(pack, number) {
        if (pack.emptySize >= number) {
            return 0;
        } else {
            return -1;
        }
    }

    //交换物品的位置
    transPositionItems(pack, pos, topos) {
        let fromItemComponent = pack.items[pos];
        let toItemComponent = pack.items[topos];
        pack.items[pos] = toItemComponent;
        pack.items[topos] = fromItemComponent;
        toItemComponent.pos = topos;
        fromItemComponent.pos = pos;
        let fromItemInfoById = pack.itemsById[fromItemComponent.templateId];
        /* fromItemInfoById.sort(function(itemComponent1, itemComponent2) { //排序
            return itemComponent1.pos > itemComponent2.pos ? 1 : -1
          })
          let toItemInfoById = this.itemsById[toItemComponent.templateId]
          toItemInfoId.sort(function(itemComponent1, itemComponent2) { //排序
            return itemComponent1.pos > itemComponent2.pos ? 1 : -1
          })*/
    }

    //移除包裹中的物品
    removeItemByItemId(pack, itemId, num) {
        let itemInfoById = pack.itemsById[itemId];
        for (let i = itemInfoById.length - 1; i >= 0; i--) {
            let p = itemInfoById[i];
            let stack = p.stack;
            if (stack > num) {
                p.stack -= num;
                return 0;
            } else if (stack === num) {
                this.removeItemByPosition(pack, p.pos);
                return 0;
            } else {
                num -= p.stack;
                this.removeItemByPosition(pack, p.pos);
            }
        }
        return 0;
    }

    //根据下标删除背包中的物品
    removeItemByPosition(pack, pos) {
        let item = pack.items[pos];
        if (!item) {
            return 1;
        }
        pack.emptySize += 1; //空格子加一
        let itemId = item.templateId;
        pack.items[pos] = null;

        let itemInfoById = pack.itemsById[itemId];
        if (itemInfoById.length === 1) {
            delete pack.itemsById[itemId];
        } else {
            for (let i in itemInfoById) {
                if (itemInfoById[i].pos === pos) {
                    itemInfoById.splice(i, 1);
                    break;
                }
            }
        }
        return 0;
    }

    removeSomeItemByPosition(pack, pos, num) {
        if (pack.items[pos].stack === num) {
            this.removeItemByPosition(pack, pos);
        } else if (pack.items[pos].stack < num) {
            return 1;
        } else {
            pack.items[pos].stack -= num;
        }
        return 0;
    }

    //获取某一物品的总数量
    getTotalNumByItemId(pack, itemId) {
        let itemInfoId = pack.itemsById[itemId]
        //查找物品是否已经存在
        if (!itemInfoId) {
            return 0;
        }

        let total = 0;
        for (let p of itemInfoId) {
            total += p.stack;
        }
        return total;
    }

    //判断道具是否足够
    isEnoughByArray(pack, items) {
        for (let i = 0; i < items.length; i++) {
            let itemId = items[i][0]
            let itemNum = items[i][1]
            let num = this.getTotalNumByItemId(pack, itemId)
            if (num < itemNum) {
                return -1
            }
        }
        return 0;
    }


    //判断道具是否足够
    isEnoughByObject(pack, items) {
        for (let itemId in items) {
            let num = this.getTotalNumByItemId(pack, itemId)
            if (num < items[itemId]) {
                return -1
            }
        }
        return 0;
    }

    //移除道具
    removeItems(pack, items) {
        for (let i = 0; i < items.length; i++) {
            let itemId = items[i][0];
            let itemNum = items[i][1];
            this.removeItemByItemId(pack, itemId, itemNum);
        }
    }

    //移除道具
    removeItemsByObject(items) {
        for (let itemId in items) {
            let itemNum = items[itemId];
            this.removeItemByItemId(pack, itemId, itemNum);
        }
    }

    //合并物品
    mergeItems(pack, frompos, topos) {
        if (frompos === topos) {
            return 1; //位置一致，不能合并
        }
        let fromItemComponent = pack.items[frompos];
        let toItemComponent = pack.items[topos];
        if (!fromItemComponent || !toItemComponent) {
            return 1; //有物品不存在不能合并
        }

        if (fromItemComponent.templateId !== toItemComponent.templateId) {
            return 1; //物品类型不同不能合并
        }

        if (fromItemComponent.bind !== toItemComponent.bind) {
            return 1; //物品类型交易类型不一样
        }

        let maxStack = itemModel.getItemConfig(fromItemComponent.templateId).maxStack || MAX_STACK;
        let fromstack = fromItemComponent.stack;
        let tostack = toItemComponent.stack;
        if (fromstack === maxStack) {
            return 0; //起始位置物品堆叠数达到上限，不能进行合并
        }

        if (tostack === maxStack) {
            //置换
            this.transPositionItems(pack, frompos, topos);
            return 0;
        }

        if (tostack + fromstack < maxStack) {
            fromItemComponent.stack = tostack + fromstack;
            this.removeItemByPosition(pack, topos);
        } else {
            let startstack = maxStack
            let endstack = tostack + fromstack - maxStack;
            fromItemComponent.stack = startstack;
            toItemComponent.stack = endstack;
        }
    }

    //合并包裹中能合并的物品
    mergePackage(pack) {
        for (let i = 0; i < this.size - 1; i++) {
            for (let j = i + 1; j < this.size; j++) {
                this.mergeItems(pack, i, j);
            }
        }
    }

    //清空包裹中的物品
    clearPackage(pack) {
        pack.itemsById = {};
        pack.items = [];
        pack.emptySize = pack.size;
    }

    //包裹整理
    arrange(pack) {
        this.mergePackage(pack) //先合并所有的物品
        //items排序
        pack.items.sort(function (item1, item2) {
            if (item1 && item2) {
                if (item1.templateId === item2.templateId) {
                    return item1.stack >= item2.stack ? 1 : -1;
                } else {
                    return item1.templateId > item2.templateId ? 1 : -1;
                }
            } else if (!item1 && item2) {
                return 1;
            } else if (item1 && !item2) {
                return -1;
            } else {
                return 1;
            }
        })
        this.initPackag(pack);
    }
}


let packageHandle = PackageHandle.getInstance();
export default packageHandle;